{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**问题：**\n",
    "假设你正在为一个电影推荐系统设计一个简单的KNN算法。我们有以下一些用户的电影评分数据，数据由两个特征组成：用户对电影A和电影B的评分，分别在1-5之间。用户的标签（电影类型偏好）是动作片（标签0）或者是喜剧片（标签1）。我们有一个新用户，他给电影A评分为3，电影B评分为4。请问这个用户可能偏好哪种类型的电影？\n",
    "\n",
    "**数据：**\n",
    "\n",
    "| 用户   | 电影A评分 | 电影B评分 | 偏好类型 |\n",
    "| ------ | --------- | --------- | -------- |\n",
    "| 用户1  | 5         | 1         | 动作片   |\n",
    "| 用户2  | 4         | 2         | 动作片   |\n",
    "| 用户3  | 2         | 5         | 喜剧片   |\n",
    "| 用户4  | 1         | 4         | 喜剧片   |\n",
    "| 用户5  | 3         | 2         | 动作片   |\n",
    "| 用户6  | 2         | 5         | 喜剧片   |\n",
    "\n",
    "你需要做以下步骤：\n",
    "1. 构造数据\n",
    "2. 创建KNN模型\n",
    "3. 使用数据训练模型\n",
    "4. 预测新用户的喜好"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. 引入核心包"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-19T11:11:11.467334Z",
     "start_time": "2025-10-19T11:11:11.462442Z"
    }
   },
   "source": [
    "# 0. 引入核心包\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ],
   "outputs": [],
   "execution_count": 11
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. X, y"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-19T11:11:13.206617Z",
     "start_time": "2025-10-19T11:11:13.201753Z"
    }
   },
   "source": [
    "X = np.array([[5, 1], [4, 2], [2, 5], [1, 4], [3, 2], [2, 5]])\n",
    "y = np.array([0, 0, 1, 1, 0, 1])  # 0=Action, 1=Comedy"
   ],
   "outputs": [],
   "execution_count": 12
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 创建 KNN 模型\n",
    "k = 1"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-19T11:11:15.826272Z",
     "start_time": "2025-10-19T11:11:15.821571Z"
    }
   },
   "source": "knn = KNeighborsClassifier(n_neighbors=1)",
   "outputs": [],
   "execution_count": 13
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-19T11:11:17.841818Z",
     "start_time": "2025-10-19T11:11:17.832439Z"
    }
   },
   "source": "knn.fit(X, y)",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ],
      "text/html": [
       "<style>#sk-container-id-2 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-2 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-2 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-2 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-2 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-2 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url();\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=1)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>KNeighborsClassifier</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_neighbors',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_neighbors&nbsp;</td>\n",
       "            <td class=\"value\">1</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('weights',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">weights&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;uniform&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('algorithm',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">algorithm&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;auto&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('leaf_size',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">leaf_size&nbsp;</td>\n",
       "            <td class=\"value\">30</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('p',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">p&nbsp;</td>\n",
       "            <td class=\"value\">2</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('metric',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">metric&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;minkowski&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('metric_params',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">metric_params&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_jobs',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_jobs&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 14
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-19T11:11:23.150256Z",
     "start_time": "2025-10-19T11:11:23.144270Z"
    }
   },
   "source": [
    "new_user = np.array([[3, 4]])\n",
    "prediction = knn.predict(new_user)"
   ],
   "outputs": [],
   "execution_count": 15
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-19T11:11:25.589525Z",
     "start_time": "2025-10-19T11:11:25.487096Z"
    }
   },
   "source": [
    "plt.title(\"User Movie Preference\", size=15) \n",
    "plt.xlabel(\"Movie A Rating\")\n",
    "plt.ylabel(\"Movie B Rating\")\n",
    "plt.grid()\n",
    "\n",
    "# 绘制原始样本点，不同的影片喜好类别用不同的颜色标记\n",
    "plt.scatter(X[y==0, 0], X[y==0, 1], c='blue', label='Action', s=100)\n",
    "plt.scatter(X[y==1, 0], X[y==1, 1], c='green', label='Comedy', s=100)\n",
    "\n",
    "# 绘制新数据点，用红色x标记，大小为8\n",
    "plt.plot(new_user[0, 0], new_user[0, 1], 'rx', markersize=8, label='New User')\n",
    "\n",
    "# 新数据最近邻索引为第一个最近邻的索引\n",
    "dist, idx = knn.kneighbors(new_user)\n",
    "nearest = X[idx[0][0]]  # 获取最近邻点的坐标\n",
    "\n",
    "print(f\"Nearest neighbor: {nearest}\")\n",
    "print(f\"Distance: {dist[0][0]:.2f}\")\n",
    "\n",
    "# 用红线标记新数据点与最近邻点的连接线\n",
    "plt.plot([new_user[0, 0], nearest[0]], [new_user[0, 1], nearest[1]], 'r--', linewidth=2)\n",
    "\n",
    "# 为每个点添加坐标文本\n",
    "for i, (x, y_val) in enumerate(zip(X[:, 0], X[:, 1])):\n",
    "    plt.text(x, y_val+0.1, f'({x}, {y_val})')\n",
    "\n",
    "# 为新数据点添加坐标文本\n",
    "plt.text(new_user[0,0], new_user[0,1]+0.1, f'({new_user[0,0]}, {new_user[0,1]})')\n",
    "\n",
    "plt.legend()\n",
    "plt.show()"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nearest neighbor: [2 5]\n",
      "Distance: 1.41\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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UDp37ixjxoyx61jbt2+Xrl27qsAIxxo4cKDUrl1bTp48KUmSJIm2tso4eOIQAURERBTvQVHChAll8uTJqpbnwoULah16niVOnNjuF1+3bl2UWiDUGB08eFDeeustq89DEJQxY0a7X4+IiIjIYUGRBkFQsWLFxJEePHigfqZOnTra/R4/fqymFXn9+rWULl1aRo0aJUWKFLG47/Pnz9WiefjwofoZGRmpFkfSjufo47oLby+fL5SR5fN83l5Gls/zRTqpjPHxnvnpdDqdLTu2b9/epgPOmTMnVieCAAdd/TEw5K5du6zut3fvXjl37pwUL15cBVFozsMwACdOnJCsWbNG2X/o0KESGhoaZT3mb4tN7RYRERHFv4iICGnZsqW69yONxqVBkb+/v6qdKVWqlET3lOXLl8fqRJCTtHbtWhUQWQpuooscCxUqpJK8hw8fblNNUbZs2eTOnTsOf1NxLhs3bpRatWqpPCtv4+3l84Uysnyez9vLyPJ5vkgnlRH377Rp0zo1KAqwJ2j55ZdfJCwsTD788ENp3bp1jM1cturWrZusWrVK1fjYExAB3nAEaufPn7e4PSgoSC2WnuesP0hnHtsdeHv5fKGMLJ/n8/YysnyeL9DBZYyP98vmLvlTp06V8PBwNUjj77//rmpbmjVrJuvXr4+25ig6eB4CItQubdmyRXLlymX3MV69eiXHjh2TTJkyxeociIiIiOwepwg1LmimQrUYus0jublLly6SM2dOlfxsL3TH/+mnn1R+D8YqunnzplqePn1q2Add/wcMGGB4PGzYMNmwYYNcvHhRzbWGGqvLly+rcZKIiIiI4r33GXKM0DUetT2orYmNadOmqZ/VqlUzWT937lxp166d+h2jZ+O1NPfu3ZOOHTuq4ClVqlRSpkwZ2bNnjxQuXDi2RSEiIiKyLyhCwvKyZctUDzMkRL/zzjvy7bffSp06dUwCF1vZ0uy2bds2k8cTJ05UCxEREZFLgiI0k2E6D+QSoXs+kq6RBU5ERETkU0HR9OnTJXv27JI7d241PQcWS1CTREREROS1QRESnjnHGBEREYmvB0WYl4yIiIjIW9mfHU1ERETkhRgUERERETEoIiIiItJjUERERETEoIiIiIhIj0EREREREYMiIiIiIj0GRUREREQMioiIiIj0GBQRERERMSgiIiIi0mNQRERERMSgiIi8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3VSxHfstW6Z/HrkHXkNyRy7NKbKl49u2bduirGvatKlaiMh3YR6s1atN580ypjWxYJJz3Exr1473U6QY8BqSu+HcZ0Tk0TfVa9dEJk2K2psJj7H++nXeTN0ZryG5E7fofUZEFFtoTkHyLRJ3Majfvn36Ltve0EPJV/AakrtgTREReQXcPLWxa/CTN1PPw2tIrsagiIiIiIhBEREREZEegyIiIiIiBkVEREREegyKiIiIiBgUEREREekxKCIiIiJiUERERESkx6CIiIiIiEERERERkR6DIiIiIiIGRURERER6DIqIiIiIGBQRERER6TEoIiIiImJQRERERKTHoIiIiIiIQRERERGRHoMiIiIiIgZFRERERHoMioiIiIgYFBERERHpMSgiIiIiYlBEREREpMegiIiIiIhBEREREZEegyIiIiIiBkVEREREbhAU7dixQxo0aCCZM2cWPz8/WbFiRbT7b9u2Te1nvty8eTPezpmIiIi8k0uDoidPnkiJEiVk6tSpdj3vzJkzEh4ebljSp0/vtHMkIiIi3xDgyhevW7euWuyFIChlypROOSciIiLyTS4NimKrZMmS8vz5cylatKgMHTpUqlSpYnVf7IdF8/DhQ/UzMjJSLY6kHc/Rx3UX3l4+Xygjy+f5vL2MLJ/ni3RSGePjPfPT6XQ6cQPIDVq+fLk0btw42mYz5BWVLVtWBTqzZs2SH3/8Uf744w8pXbq0xecgaAoNDY2yfsGCBZI4cWKHloGIiIicIyIiQlq2bCkPHjyQ5MmTO+U1PCoosqRq1aqSPXt2FRzZWlOULVs2uXPnjsPfVESxGzdulFq1aklgYKB4G28vny+UkeXzfN5eRpbP80U6qYy4f6dNm9apQZFHNp8ZK1++vOzatcvq9qCgILWYw4Vy1h+kM4/tDry9fL5QRpbP83l7GVk+zxfo4DLGx/vl8eMUHTlyRDJlyuTq0yAiIiIP59KaosePH8v58+cNj8PCwlSQkzp1atUkNmDAALl+/br88MMPavukSZMkV65cUqRIEXn27JnKKdqyZYts2LDBhaUgIiIib+DSoOjAgQNSvXp1w+PevXurn23btpV58+apMYiuXLli2P7ixQvp06ePCpSQJF28eHHZtGmTyTGIiIiIPC4oqlatmkSX543AyFj//v3VQkRERORoHp9TREREROQIDIqIiIiIGBQRERER6TEoIiIiImJQRERERKTHoIiIiIiIQRERERGRHoMiIiIiIgZFRERERHoMioiIiIgYFBERERHpMSgiIiIiYlBEREREpMegiIiIiIhBEREREZEegyIiIiIiBkVERETkLHfv3pX06dPLpUuX4v21K1asKEuXLrXrOQyKiIiIyClGjhwpjRo1kpw5cxrW+fn5RVkWLlxo13F37NghDRo0kMyZM6vnr1ixIso+gwcPls8//1xev35t83EZFBEREZHDRUREyOzZs6VDhw5Rts2dO1fCw8MNS+PGje069pMnT6REiRIydepUq/vUrVtXHj16JGvXrrX5uAF2nQURERGRDRCMBAUFqWYscylTppSMGTNKbCHgwRKdBAkSSL169VQtVP369W06LmuKiIiIyOF2794tZcqUsbita9eukjZtWilfvrzMmTNHdDqd409ARB1/586dNu/PmiIiIiJyuMuXL6ucH3PDhg2TGjVqSOLEiWXDhg3SpUsXefz4sfTo0cPh54DXv3r1qsor8vePuR6IQRERERE53LNnzyRRokRR1n/xxReG30uVKqXyg8aNG+eUoCg4OFgFRM+fP1e/x4TNZ0RERORwadKkkXv37sW4X4UKFeTatWsqcHG0f/75R5IkSWJTQAQMioiIiMjhSpYsKSdPnoxxvyNHjkiqVKlUUrajHT9+XNVG2YrNZ0RERORwtWrVUmMFobYIQQ/8/vvvcuvWLdUjDU1rGzdulFGjRknfvn3tOjZykM6fP294HBYWpoKr1KlTS/bs2Q3rkWRdu3Ztm4/LmiIiIiJyuGLFiknp0qVl0aJFhnWBgYFqbKFKlSqpmqQZM2bIhAkTZMiQIYZ9MPo1BmTctm2b1WMfOHBA1QBptUC9e/dWv3/55ZeGfa5fvy579uyRDz/80OZzZk0REREROQR61t+9q/8dP7/44kvp37+fdOzYUfX+qlOnjlqig1ofjGOEwRmtqVatWozd+KdMmSLt2rWTrFmz2nz+rCkiIiKiOLl/X2TyZJF8+URy59avw89evepLgQIfy8mT120+1po1a2TgwIGGJrfYwpxrw4cPt+s5rCkiIiKiWFu/XqRJE0zroX9s3Av/4kUsvWTjRhHMzRoSEvPx0D3fEfr06WP3c1hTRERERLEOiDCDxtOn+qYz8xYtbR22Yz/s785cGhTZMsutOSReIXELXffy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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 16
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
